import os
import json
import cv2
import application

def LogD(*args):
    DebugPrint(*args)

def LogI(*args):
    LogD(*args)

g_GlobalTempDisable = [
]

def addDisableAction(actid):
    global g_GlobalTempDisable
    g_GlobalTempDisable.append(actid)

def removeDisableAction(actid):
    global g_GlobalTempDisable
    if actid not in g_GlobalTempDisable:
        return
    g_GlobalTempDisable.remove(actid)

def ReadBRBGImage(imgfile, max_pixel_sqdiff = 20):
    imgobj = cv2.imread(imgfile, cv2.IMREAD_UNCHANGED)
    # 分离B的alpha通道
    alpha = imgobj[:, :, 3]
    mask = (alpha > 0).astype('uint8')
    mask_3c = cv2.merge([mask, mask, mask])
    # 创建掩码
    imgmask = mask_3c
    # 提取图片的BGR三通道
    imgobj = imgobj[:, :, 0:3]
    imgpixels = cv2.countNonZero(mask)
    threshold = imgpixels * max_pixel_sqdiff
    return imgobj, imgmask, threshold

class Action:

    def __init__(self, uuidstr, conffile):
        self._uuid = uuidstr
        self._imgpixels = 0
        self._resultimgpixels = 0
        self._configfile = conffile
        f = open(self._configfile, "r", encoding="utf8")
        data = f.read()
        f.close()
        self._dirpath = os.path.dirname(conffile)
        self._data = json.loads(data)
        # 加载图像为opencv的格式
        if "Image" in self._data:
            imgfile = os.path.join(self._dirpath, self._data["Image"])
            self._imgobj = cv2.imread(imgfile)
        else:
            self._imgobj = None

    def GetName(self):
        return self._data.get("Name", "Unkonw")
    
    def GetRecognitionRate(self):
        return self._data.get("RecognitionRate", 0.9)
    
    def GetExecuteType(self):
        return self._data.get("ClickType", "Once")
    
    def GetExecuteTimeout(self):
        return self._data.get("ExecuteIntervalTime", 1000)
    
    def GetExecuteRetryTime(self):
        return self._data.get("RetryTime", 0)
    
    def GetBreakTime(self):
        return self._data.get("BreakTime", 0)
    
    def GetRect(self):
        w = self._imgobj.shape[1]
        h = self._imgobj.shape[0]
        return (w, h)
    
    def Click(self):
        pos = self.GetClickPos()
        if -1 == pos[0] and -1 == pos[1]:
            return
        clicktype = self.GetExecuteType()
        if "Button" == clicktype:
            LogD(f"Touch pos: {pos[0]} {pos[1]}")
            g_ActMgr.TouchPoint(pos[0], pos[1])
        elif "LongPress" == clicktype:
            LogD(f"Long press pos: {pos[0]} {pos[1]}")
            g_ActMgr.TouchPoint(pos[0], pos[1])

    
    def GetAdbShellList(self):
        if "AdbShell" == self._data["Type"]:
            return self._data["AdbShellList"]
        return []
    
    def GetPkgName(self):
        if "StartAPK" == self._data["Type"]:
            return self._data["PkgName"]
        return []
    
    def MatchTemplate(self):
        m = g_ActMgr.GetMainScreenshot()
        if m is None:
            return 0, 0, 0, 0
        imgobj = self._imgobj
        result = cv2.matchTemplate(m, imgobj, cv2.TM_CCOEFF_NORMED)
        minval, maxval, min_loc, max_loc = cv2.minMaxLoc(result)
        return minval, maxval, min_loc, max_loc
    
    def GetClickPos(self):
        LogD("Click:", self._uuid, self._data["Name"])
        _, maxval, _, maxloc = self.MatchTemplate()
        LogD("Click:", self._uuid, self._data["Name"], maxval, self.GetRecognitionRate())
        if maxval <= self.GetRecognitionRate():
            return (-1, -1)
        w, h = self.GetRect()
        cpt = self._data.get("ClickPosType", "Center")
        if "BottomCenter" == cpt:
            # 点击中下方
            return (maxloc[0] + w / 2, maxloc[1] + h)
        elif "TopCenter" == cpt:
            # 点击中下方
            return (maxloc[0] + w / 2, maxloc[1])
        elif "RightCenter" == cpt:
            # 点击右边中间
            LogI(maxloc[0], maxloc[1], w, h)
            LogI(maxloc[0] + w, maxloc[1] + h / 2)
            return (maxloc[0] + w, maxloc[1] + h / 2)
        elif "LeftCenter" == cpt:
            # 点击右边中间
            return (maxloc[0], maxloc[1] + h / 2)
        elif "RightBottom" == cpt:
            # 点击右下角
            return (maxloc[0] + w, maxloc[1] + h)
        elif "LeftBottom" == cpt:
            # 点击左下角
            return (maxloc[0], maxloc[1] + h)
        elif "LeftTop" == cpt:
            # 点击左上角
            return (maxloc[0], maxloc[1])
        elif "RightTop" == cpt:
            # 点击右上角
            return (maxloc[0] + w, maxloc[1])
        elif "Offset" == cpt:
            offsetpos = self._data.get("Offset", [0, 0])
            return (maxloc[0] + offsetpos[0], maxloc[1] + offsetpos[1])
        else:
            # 默认就点击中间
            return (maxloc[0] + w / 2, maxloc[1] + h / 2)
        
    def Check(self):
        if "Button" == self._data["Type"]:
            r = self.GetClickPos()
            if -1 == r[0] and -1 == r[1]:
                return False
            return True
        else:
            return self.Execute()

    def Execute(self):
        # 不同action执行不同的，button就click了
        if "CheckAPP" == self._data["Type"]:
            import application
            pkgname = self._data["Package"]
            r = application.g_App.getThread("scrcpy").checkAPPIsRunning(pkgname)
            return r
        elif "StartAPP" == self._data["Type"]:
            import application
            pkgname = self._data["Package"]
            r = application.g_App.getThread("scrcpy").startAPP(pkgname)
        elif "StopAPP" == self._data["Type"]:
            import application
            pkgname = self._data["Package"]
            r = application.g_App.getThread("scrcpy").stopAPP(pkgname)
        else:
            self.Click()
            return True

class ActionManager:

    def __init__(self):
        self._actions = {}
        self._m = None

    def GetAllActions(self):
        l = []
        for dirname, actobj in self._actions.items():
            s = (actobj.GetName(), dirname)
            l.append(s)
        return l

    def LoadAllActions(self):
        s = os.path.abspath(__file__)
        s = os.path.join(os.path.dirname(s), "actions")
        if not os.path.exists(s):
            s = os.path.join(os.getcwd(), "actions")
        for root, dirs, _ in os.walk(s):
            for dirname in dirs:
                actiondir = os.path.join(root, dirname)
                conffile = os.path.join(actiondir, "config.json")
                if not os.path.exists(conffile):
                    continue
                actobj = Action(dirname, conffile)
                LogI(f"load action [{dirname}]-{actobj.GetName()}")
                self._actions[dirname] = actobj
            break

    def GetActionName(self, actid):
        actobj = self.GetAction(actid)
        if not actobj:
            return "Unknow"
        return actobj.GetName()

    def GetMainScreenshot(self):
        import application
        threadobj = application.g_App.getThread("scrcpy")
        return threadobj.getFrame()
    
    def GetAction(self, actid: str):
        if actid not in self._actions:
            return
        actobj: Action = self._actions[actid]
        return actobj

    def SetClientProxy(self, c):
        self._client = c

    def GetClientProxy(self):
        return self._client
    
    def LongPressPoint(self, x, y, sec):
        #self._client.control.swipe(x, y, 9999, 9999, move_steps_delay = 0.01)
        self._client._thread.PushCommand(("longpress", x, y, sec))
    
    def Swipe(self, x, y, x1, y1, sec = 0.1):
        #self._client.control.swipe(x, y, x1, y1)
        application.g_App.pushMessage("scrcpy", "swipe", x, y, x1, y1, sec)
    
    def TouchPoint(self, x, y):
        application.g_App.pushMessage("scrcpy", "touch", x, y)

    def KeyEvent(self, keycode):
        #self._client.control.keycode(keycode, scrcpy.ACTION_DOWN)
        #self._client.control.keycode(keycode, scrcpy.ACTION_UP)
        self._client._thread.PushCommand(("keycode", keycode))

    def DebugCheckShow(self, x, y):
        self._client._thread.PushCommand(("debugshow", x, y))

g_ActMgr = ActionManager()
